(function(window){

    var requireSize         = 0
    ,   successRequireSize  = 0
    ,   errorRequireSize    = 0
    ,   arrayUnique = function(){
        this.sort();
        var re=[this[0]];
        for(var i = 1; i < this.length; i++) {
            if( this[i] !== re[re.length-1]) {
                re.push(this[i]);
            }
        }
        return re;
    }
    ,   require = function(url, callback){
        this.path = this.url = url;
        this.packageWarehouse = 'six7_modules';
        this.callback = callback || null;
        this.init();
    };

    require.prototype = {
        init        : function(){
            requireSize += 1;
            warehouse[this.path] = {
                code    : null,
                status  : false
            };
            this.onload();
        },
        analysisID  : function(id){
            var idArray = id.split('/');
            var finalID = '';
            if(idArray[0] === ''){
                finalID = id;
            }else if(idArray[0] === '.'){
                idArray.shift();
                id = '/'+idArray.join('/');
                finalID = '/' + this.url + id;
            }else if(idArray[0] === '..'){
                id = '/'+idArray.join('/');
                finalID = '/' + this.url + id;
            }else{
                idArray[0] = this.packageWarehouse +'/' + idArray[0];
                id = '/'+idArray.join('/');
                finalID = id;
            };

            finalID = finalID.substr(1);

            if(finalID.indexOf('../') !== -1){
                var newFinalID = [];
                finalID = finalID.split('/');
                for(var i in finalID){
                    if(finalID[i] !== '..'){
                        newFinalID.push(finalID[i]);
                    }else{
                        if(newFinalID.length)
                            newFinalID.pop();
                        else{
                            newFinalID = finalID;
                            break;
                        };
                    }
                };
                finalID = newFinalID;
                newFinalID = null;
                finalID = finalID.join('/');
            };

            return finalID;
        },
        fileName    : function(){

            for(var i in this.final){
                var final       = this.final[i]
                ,   finalArray  = final.split('/')
                ,   length      = finalArray.length
                ,   ending      = finalArray[length - 1]
                ,   endingArray = ending.split('.')
                ,   fileName;

                if(endingArray.length === 2 && endingArray[1] === 'js'){
                    fileName = [endingArray.join('.')];
                }else if(ending == ""){
                    fileName = ['index.js'];
                }else{
                    fileName = [endingArray.join('.')+'.js', endingArray.join('.')+'/index.js'];
                };

                var finalArr = [];

                for(var j in fileName){
                    var final = finalArray;
                    final[final.length - 1] = fileName[j];
                    final = final.join('/');
                    finalArr.push(final);
                };
                this.idSize += finalArr.length;
                this.next(i, finalArr);

            };
        },
        onload      : function(){
            var that = this;
            var url = this.url;
            var callback = this.callback;
            if(callback)
                var returnJSON = {finally: callback.finally, id: callback.id};
            util.ajax({
                url : url+'?time='+new Date().getTime(),
                param: {url: url},
                success : function(code, param){
                    that.code = util.deleteNotes(code);
                    that.analysisCode();

                    successRequireSize += 1;

                    if(callback){
                        returnJSON.status = true;
                        returnJSON.url = param.url;
                    };
                    callback && callback(returnJSON);

                    if(requireSize === successRequireSize + errorRequireSize)
                        that.start();
                },
                error   : function(param){

                    errorRequireSize += 1;

                    if(callback) {
                        returnJSON.status = false;
                        returnJSON.url = param.url;
                    };
                    callback && callback(returnJSON);

                    if(requireSize === successRequireSize + errorRequireSize)
                        that.start();
                }
            });
        },
        analysisCode: function(){
            var requireURI = util.parseDependencies(this.code);
            this.id = requireURI;
            this.idSize = 0;//requireURI.length;
            this.url = this.url.split('/');
            this.url.pop();
            this.url = this.url.join('/');
            this.final = [];
            for(var i in requireURI){
                var url = this.analysisID(requireURI[i]);
                this.final.push(url);
            };

            if(this.final.length == 0)
                warehouse[this.path].code = this.code;
            else
                this.fileName();
        },
        next        : function(id, finalArr){
            var that        = this
            ,   thisIndex   = 0
            ,   length      = finalArr.length
            ,   Finally     = []
            ,   success     = function(id) {
                if (Finally[0] != Finally[1] && !Finally[0]) {
                    final = finalArr[1];
                } else {
                    final = finalArr[0];
                };

                that.final[id] = final;

                if(that.replaceID === that.idSize){
                    that.replace();
                };

            }
            ,   final;

            for(var i in finalArr){
                var callback = function(json){
                    Finally[json.finally] = json.status;
                    thisIndex += 1;

                    that.replaceID = that.replaceID ? that.replaceID + 1 : 1;

                    if(thisIndex === length){
                        success(json.id);
                    };
                };

                if(undefined === warehouse[finalArr[i]]){
                    callback.finally = i;
                    callback.id = id;
                    new require(finalArr[i], callback);
                }else{
                    var returnJSON = {finally: i, id: id, status: false, url: finalArr[i]};
                    callback(returnJSON);
                };

            };
        },
        replace     : function(){
            for(var i in this.id){
                var _require = ["require('"+this.id[i]+"')", 'require("'+ this.id[i] +'")'];
                var correctRequire = 'require("'+ this.final[i] +'")';
                for(var j in _require){
                    if(this.code.indexOf(_require[j]) >= 0){
                        this.code = this.code.replace(_require[j], correctRequire);
                    };
                }
            };

            warehouse[this.path].code = this.code;
        },
        start       : function(){
            console.clear();
            warehouse[startAPP].status = true;
            warehouse[startAPP].code = new Function(warehouse[startAPP].code);
            warehouse[startAPP].code();
        }
    };

    var _require = function(url, callback){
        return new require(url, callback);
    };

    var window_require = function(id){
        if(!warehouse[id].status){
            warehouse[id].status = true;
            new Function(warehouse[id].code)();
            warehouse[id].code = module.exports;

            window.exports = {};
            window.module = {
                exports: window.exports
            };
        };
        return warehouse[id].code;
    };

    var util = {
        ajax: function(options){
            var _xhr = new XMLHttpRequest();
            _xhr.open("GET", options.url, options.async || true);
            try {
                _xhr.send(null);
            }catch (err){
                options.error && options.error(options.data);
            };

            _xhr.onreadystatechange = function () {
                if (_xhr.readyState == 4) {
                    var status = _xhr.status;
                    if (status == 200 || status == 0 && _xhr.response) {
                        options.success && options.success(_xhr.response, options.param);
                    } else {
                        options.error && options.error(options.param);
                    }
                    _xhr = null;
                };
            };
        },
        parseDependencies: function(code) {
            var SLASH_RE = /\\\\/g
            var REQUIRE_RE = /"(?:\\"|[^"])*"|'(?:\\'|[^'])*'|\/\*[\S\s]*?\*\/|\/(?:\\\/|[^\/\r\n])+\/(?=[^\/])|\/\/.*|\.\s*require|(?:^|[^$])\brequire\s*\(\s*(["'])(.+?)\1\s*\)/g
            var ret = []
            code.replace(SLASH_RE, "")
                // 匹配require关键词，找出依赖关系
                .replace(REQUIRE_RE, function(m, m1, m2) {
                    if (m2) {
                        ret.push(m2)
                    }
                })
            return ret;
        },
        deleteNotes: function(code){
            return code.replace(/(?:^|\n|\r)\s*\/\*[\s\S]*?\*\/\s*(?:\r|\n|$)/g, '\n').replace(/(?:^|\n|\r)\s*\/\/.*(?:\r|\n|$)/g, '\n');
        }
    };

    var warehouse = {};
    var startAPP = document.getElementsByTagName('script');

    for(var i = 0; i < startAPP.length; i++){
        if(startAPP[i].getAttribute('six7-main')){
            startAPP = startAPP[i].getAttribute('six7-main');
            break;
        };
    };

    _require(startAPP);

    window.require = window_require;
    window.exports = {};
    window.module = {
        exports: window.exports
    };
})(window);